<!DOCTYPE html>
<title>Test media preloading behaviour with different conditions.</title>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<script>
var tests = [
  {
    name: 'regular conditions',
    conditions: {
      dataSaver: false,
      cellular: false,
    },
    expectations: {
      default: 'metadata',
      allowed: [ 'none', 'metadata', 'auto' ]
    }
  },
  {
    name: 'cellular connections',
    conditions: {
      dataSaver: false,
      cellular: true,
    },
    expectations: {
      default: 'metadata',
      allowed: [ 'none', 'metadata' ]
    }
  },
  {
    name: 'cellular connections with Data Saver',
    conditions: {
      dataSaver: true,
      cellular: true,
    },
    expectations: {
      default: 'metadata',
      allowed: [ 'none', 'metadata' ]
    }
  },
  {
    name: 'Data Saver',
    conditions: {
      dataSaver: true,
      cellular: false,
    },
    expectations: {
      default: 'metadata',
      allowed: [ 'none', 'metadata', 'auto' ]
    }
  },
];

function checkPreloadAttribute(media, value, expected) {
    // Use IDL attribute.
    media.removeAttribute("preload");
    media.preload = value;
    assert_equals(media.getAttribute("preload"), value);
    assert_equals(media.preload, expected);

    // Use. content attribute.
    media.removeAttribute("preload");
    media.setAttribute("preload", value);
    assert_equals(media.preload, expected);
    assert_equals(media.getAttribute("preload"), value);
}

var asyncTests = tests.map(test => async_test('Testing autoplay behaviour for ' + test.name));

var currentTest = 0;
function runNextTest() {
  asyncTests[currentTest].done();

  ++currentTest;
  if (currentTest == tests.length)
    return;

  asyncTests[currentTest].step_func(runTest(asyncTests[currentTest], tests[currentTest]));
}

function runTest(t, test) {
  // Sanity checks for 'conditions'.
  assert_true('dataSaver' in test.conditions);
  assert_true('cellular' in test.conditions);

  internals.setSaveDataEnabled(test.conditions.dataSaver);
  if (test.conditions.cellular)
    internals.setNetworkConnectionInfoOverride(true, 'cellular3g', '4g', 100, 2.0);
  else
    internals.setNetworkConnectionInfoOverride(true, 'wifi', '4g', 100, 2.0);

  t.add_cleanup(() => {
    internals.setSaveDataEnabled(false);
    internals.clearNetworkConnectionInfoOverride();
  });

  var media = document.createElement('video');

  // Test IDL without any value.
  assert_equals(media.preload, test.expectations.default);
  assert_false(media.hasAttribute('preload'));

  // Test allowed values.
  [ 'none', 'metadata', 'auto' ].forEach(t.step_func(preload => {
    var expected = test.expectations.allowed.includes(preload) ? preload : test.expectations.default;
    checkPreloadAttribute(media, preload, expected);
  }));

  // Test not allowed values.
  [ 'default', 'foo' ].forEach(preload => {
    checkPreloadAttribute(media, preload, test.expectations.default);
  });

  // Test loading events.
  var expectedLoading = 4;
  [ '', 'none', 'metadata', 'auto' ].forEach(preload => {
    var media = document.createElement('video');
    media.preload = preload;
    media.src = 'resources/test.ogv';
    assert_equals(media.readyState, HTMLMediaElement.HAVE_NOTHING);

    switch (media.preload) {
      case 'none':
        media.onloadedmetadata = t.unreached_func();
        media.onprogress = t.unreached_func();

        media.onsuspend = t.step_func(_ => {
          assert_equals(media.readyState, HTMLMediaElement.HAVE_NOTHING);
          --expectedLoading;
          if (expectedLoading == 0)
            runNextTest();
        });
        break;
      case 'metadata':
        media.onloadedmetadata = t.step_func(_ => {
          assert_greater_than_equal(media.readyState, HTMLMediaElement.HAVE_METADATA);
          --expectedLoading;
          if (expectedLoading == 0)
            runNextTest();
        });
        break;
      case 'auto':
        if (media.readyState == HTMLMediaElement.HAVE_ENOUGH_DATA) {
          --expectedLoading;
          break;
        }

        media.oncanplaythrough = t.step_func(_ => {
          assert_equals(media.readyState, HTMLMediaElement.HAVE_ENOUGH_DATA);
          --expectedLoading;
          if (expectedLoading == 0)
            runNextTest();
        });
        break;
    }
  });
}

asyncTests[currentTest].step_func(runTest(asyncTests[currentTest], tests[currentTest]));

</script>
